Skip to content

fix(policy)!: Fix SatisfiableItem id calculation for Thresh nodes#439

Open
ValuedMammal wants to merge 1 commit intobitcoindevkit:masterfrom
ValuedMammal:fix/policy_id_calculation
Open

fix(policy)!: Fix SatisfiableItem id calculation for Thresh nodes#439
ValuedMammal wants to merge 1 commit intobitcoindevkit:masterfrom
ValuedMammal:fix/policy_id_calculation

Conversation

@ValuedMammal
Copy link
Copy Markdown
Collaborator

@ValuedMammal ValuedMammal commented Apr 11, 2026

Description

Fixes #123.

SatisfiableItem::id() previously produced unstable ids for Thresh nodes because SatisfiableItem::Thresh contains Vec<Policy>, and Policy carries contribution and satisfaction — both of which are runtime-dependent (they differ based on whether private or public keys are loaded into the signer). This meant the policy node id changed for the same descriptor structure depending on signing context, breaking any use-case that persists ids (e.g. storing signing paths in a database keyed by policy id).

The fix special-cases Thresh in SatisfiableItem::id(), computing the checksum preimage from only structural data: thresh(<threshold>,[<child_id0>,<child_id1>,...])

Child ids are themselves already stable (leaf ids are unaffected). Leaf item ids are unchanged — they still use JSON serialization of their content, which contains no runtime state.

Notes to the reviewers

No library API surface changes — method signatures, types, and public fields are all unchanged. The breaking nature of this change is behavioral: the id derivation for Thresh nodes produces different values than before, so any ids persisted prior to this fix (e.g. as database keys for signing paths) are now stale and must be recomputed from the descriptor. This is documented in the id() doc comment under a # Migration note heading, with a link back to issue #123.

The one hardcoded Thresh id in tests/wallet.rs (test_taproot_psbt_populate_tap_key_origins_repeated_key) was updated from "rn4nre9c" to "vj73w7cm" to reflect the new stable id.

Changelog notice

Fixed

  • fix(policy)!: SatisfiableItem::id() now produces a stable id for Thresh nodes regardless of which signing keys are present in the descriptor. Previously the id varied based on runtime contribution/ satisfaction state. Breaking (behavioral): no API signatures change, but any persisted Thresh policy node ids must be recomputed from the descriptor.

Checklists

All Submissions:

Bugfixes:

  • This pull request breaks the existing API (?)
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

by special-casing Thresh to derive the checksum payload
from the structural data only (threshhold and child ids).
Prevents the id from being influenced by policy satisfaction/
contribution which depend on runtime state.

BREAKING:
As this can permanently change the item's id calculation,
any previously persisted ids should be recomputed from the
descriptor. The id calculation should be stable from now on.
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.84%. Comparing base (fb7681a) to head (0a491ec).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #439      +/-   ##
==========================================
- Coverage   80.04%   79.84%   -0.20%     
==========================================
  Files          24       24              
  Lines        5336     5344       +8     
  Branches      242      242              
==========================================
- Hits         4271     4267       -4     
- Misses        987      999      +12     
  Partials       78       78              
Flag Coverage Δ
rust 79.84% <100.00%> (-0.20%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Do not include satisfaction in policy id calculation

1 participant